package com.nitobi.test
{
	import com.nitobi.harvest.model.HarvestModel;
	import com.nitobi.harvest.service.HarvestService;
	import com.nitobi.util.Encryption;
	import com.nitobi.test.Constants;
	
	import flash.events.Event;
	
	import flexunit.framework.TestCase;
	
	public class HarvestServiceTest extends TestCase
	{
		/**
		 * no test created for checking daily entries
		 * since the user may not have any entries
		 * when running the tests
		 * **/
		
		private var _model:HarvestModel;
		private var _service:HarvestService;
		private var _xml:XML;
		private var _dayEntryId:String;

		override public function setUp():void
		{
			Encryption.writeEncryptedStringSetting("companyName", Constants.COMPANY_NAME);
			Encryption.writeEncryptedStringSetting("harvestUser", Constants.HARVEST_USER);
			Encryption.writeEncryptedStringSetting("harvestPass", Constants.HARVEST_PASS);		
			
			_model = HarvestModel.getInstance();
			_service = HarvestService.getInstance();
			_service.init();	
			
			_xml = new XML();	
			_dayEntryId = new String();
		}

		public function testHarvestService():void
		{	
			_service.getHarvestDataDaily( addAsync(handleGetHarvestDataDailyResult, Constants.TIMEOUT_MS), _service.harvestError);
		}
		
		private function handleGetHarvestDataDailyResult(evt:Event):void
		{
			var xml:XML = new XML(evt.target.data);
			_xml = xml;
			// reset the model so we see if checkProjectListTest gets the right data
			_model.todaysHours = 0;
			_model.dailyEntriesAC.removeAll();
			_model.projectListAC.removeAll();
			checkProjectListTest();
		}
	
		private function checkProjectListTest():void
		{
			_service.populateProjectList(_xml);
			assertTrue("At least 1 project attached to user", _model.projectListAC.length > 0);
			// call the create task test
			createTaskTest();
		}
		
		private function createTaskTest():void
		{
			var notes:String = Constants.CREATE_TASK_NOTE;
			var hours:String = "10.00";
			var projectId:String = _model.projectListAC[0]._id;
			var taskId:String = _model.projectListAC[0]._taskList[0]._id;
			_service.createHarvestEntry(notes, hours, projectId, taskId, addAsync(handleCreateTask, Constants.TIMEOUT_MS), _service.harvestError);
		}
		
		private function handleCreateTask(evt:Event):void
		{
			var createEntryResponse:XML = new XML(evt.target.data);
			_dayEntryId = createEntryResponse.day_entry.id.toString();
			assertTrue("New entry was created", _dayEntryId.length > 0);
			assertEquals("Note in new entry matches note passed in", Constants.CREATE_TASK_NOTE, createEntryResponse.day_entry.notes.toString());
			assertEquals("Hours equals 10.00", "10.00", createEntryResponse.day_entry.hours.toString());
			assertEquals("ProjectId matches", _model.projectListAC[0]._id, createEntryResponse.day_entry.project_id);
			assertEquals("TaskId matches", _model.projectListAC[0]._taskList[0]._id, createEntryResponse.day_entry.task_id); 
			// call the update task test
			updateTaskTest();
		}
		
		private function updateTaskTest():void
		{
			var notes:String = Constants.EDIT_TASK_NOTE;
			var hours:String = "5.00";
			var projectId:String = _model.projectListAC[0]._id;
			var taskId:String = _model.projectListAC[0]._taskList[0]._id;
			_service.updateHarvestEntry(projectId, taskId, hours, notes, Number(_dayEntryId), addAsync(handleUpdateTask, Constants.TIMEOUT_MS), _service.harvestError);	
		}
		
		private function handleUpdateTask(evt:Event):void
		{
			var updateTaskResponse:XML = new XML(evt.target.data);
			assertEquals("DayEntryId matches", _dayEntryId, updateTaskResponse.day_entry.id);
			assertEquals("Note updated", Constants.EDIT_TASK_NOTE, updateTaskResponse.day_entry.notes.toString());
			assertEquals("Hours updated to 5.00", "5.00", updateTaskResponse.day_entry.hours.toString());
			assertEquals("ProjectId matches", _model.projectListAC[0]._id, updateTaskResponse.day_entry.project_id);
			assertEquals("TaskId matches", _model.projectListAC[0]._taskList[0]._id, updateTaskResponse.day_entry.task_id); 			
			// call start task timer test
			startTaskTimerTest();
		}
		
		private function startTaskTimerTest():void
		{
			_service.toggleTimer(Number(_dayEntryId), addAsync(handleStartTaskTimer, Constants.TIMEOUT_MS), _service.harvestError);
		}
		
		private function handleStartTaskTimer(evt:Event):void
		{
			var startTimerResponse:XML = new XML(evt.target.data);
			assertEquals("DayEntryId matches", _dayEntryId, startTimerResponse.day_entry.id);
			assertEquals("ProjectId matches", _model.projectListAC[0]._id, startTimerResponse.day_entry.project_id);
			assertEquals("TaskId matches", _model.projectListAC[0]._taskList[0]._id, startTimerResponse.day_entry.task_id);
			assertEquals("Hours matches", "5.00", startTimerResponse.day_entry.hours.toString());	
			assertEquals("Note matches", Constants.EDIT_TASK_NOTE, startTimerResponse.day_entry.notes.toString());	
			assertNotNull(startTimerResponse.day_entry.timer_started_at);	
			// call stop task timer test
			stopTaskTimerTest();
		}
		
		private function stopTaskTimerTest():void
		{
			_service.toggleTimer(Number(_dayEntryId), addAsync(handleStopTaskTimer, Constants.TIMEOUT_MS), _service.harvestError);
		}
		
		private function handleStopTaskTimer(evt:Event):void
		{
			var stopTimerResponse:XML = new XML(evt.target.data);
			assertEquals("DayEntryId matches", _dayEntryId, stopTimerResponse.day_entry.id);
			assertEquals("ProjectId matches", _model.projectListAC[0]._id, stopTimerResponse.day_entry.project_id);
			assertEquals("TaskId matches", _model.projectListAC[0]._taskList[0]._id, stopTimerResponse.day_entry.task_id);
			assertEquals("Hours matches", "5.00", stopTimerResponse.day_entry.hours.toString());	
			assertEquals("Note matches", Constants.EDIT_TASK_NOTE, stopTimerResponse.day_entry.notes.toString());			
			// call the delete task test
			deleteTaskTest();	
		}
		
		private function deleteTaskTest():void
		{
			_service.deleteHarvestEntry(_dayEntryId, addAsync(handleDeleteTask, Constants.TIMEOUT_MS), _service.harvestError);
		}
		
		private function handleDeleteTask(evt:Event):void
		{
			assertTrue("Space returned", evt.target.data == " ");
		}
	}
}